#include <iostream.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "stack_class.h"
enum Boolean{False,True};

class Calculator
{
public:
       Calculator(void) {}
       void Run(void);
       void Clear(void);
private:      
       Stack <int> S;
       void Enter(int num) ;
       Boolean GetTwoOperands(int& opnd1,int& opnd2);
       void Compute(char op);
};

void Calculator::Enter(int num)
{
   S.Push(num);
}

Boolean Calculator::GetTwoOperands(int& opnd1, int& opnd2)
{
    if( S.StackEmpty() )        
    {
        cerr<<"Missing operand!"<<endl;       
        exit(1);
    }
    opnd1 = S.Pop();
    if( S.StackEmpty() )        
    {
        cerr<<"Missing operand!"<<endl;       
        exit(1);
    }
    opnd2 = S.Pop();
    return True;
}

void Calculator::Compute(char op)
{
    Boolean result;
    int operand1,operand2;
    result = GetTwoOperands(operand1, operand2);
    if(result == True )  
    {
        switch(op)         
        {
            case '+' : S.Push(operand2+operand1); break;
            case '-' : S.Push(operand2-operand1); break;
            case '*' : S.Push(operand2*operand1); break;
            case '/' : if(operand1 == 0)
                       {
                           cerr<<"Divide by 0!"<<endl;    
                           S.ClearStack();
                       }
                       else
                       S.Push(operand2/operand1); break;
            case '^' : S.Push((int)pow(operand2,operand1));
                       break;
        } 
        cout<<"="<<S.Peek()<<" ";
    }
    else S.ClearStack();
}

void Calculator::Run(void)
{
    char c[20];
    while(cin>>c , *c!='q')
    {
        
        switch(*c)
        {
            case 'c' : S.ClearStack();break;
            case '-' : if( strlen(c)>1 )  Enter(atoi(c));
                       else Compute(*c);
                       break;
            case '+' : 
            case '*' :
            case '/' :
            case '^' :
                 Compute(*c); break;
            default:
                 Enter( atoi(c) );
                 break;
        }
    }
}

void Calculator::Clear(void) 
{
    S.ClearStack();         
}

int main()
{
    Calculator sta;
    sta.Run();
//    sta.Compute();
    system("pause");
    return 0;
} 

